package com.bestcem.xm.deliver.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bestcem.xm.common.core.annotation.XmGet;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.component.mybatis.base.ResultPage;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.deliver.controller.param.EmailRecordsPageParam;
import com.bestcem.xm.deliver.controller.param.SmsRecordsPageParam;
import com.bestcem.xm.deliver.controller.param.SurveyDetailParam;
import com.bestcem.xm.deliver.controller.param.SurveyListParam;
import com.bestcem.xm.deliver.controller.v2.param.*;
import com.bestcem.xm.deliver.controller.v2.vo.DedicatedDeliverVo;
import com.bestcem.xm.deliver.controller.v2.vo.DeliverEmailRecordVo;
import com.bestcem.xm.deliver.controller.v2.vo.DeliverSmsRecordVo;
import com.bestcem.xm.deliver.controller.v2.vo.DeliverStoreVo;
import com.bestcem.xm.deliver.entity.*;
import com.bestcem.xm.deliver.enums.DeliverStatusEnum;
import com.bestcem.xm.deliver.grpc.client.QdesGrpcClient;
import com.bestcem.xm.deliver.grpc.v1.services.DeliverStatus;
import com.bestcem.xm.deliver.service.*;
import com.bestcem.xm.deliver.util.PageUtil;
import com.bestcem.xm.qdes.grpc.v1.services.Project;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.CompletableFuture;

import static com.bestcem.xm.common.core.enums.ReqErrorCodeEnum.PARAM_LOST;
import static com.bestcem.xm.deliver.enums.WechatMpdeliverMpTypeEnum.WECHATMPDELIVER_MP_TTYPE_DIRECT;
import static com.bestcem.xm.deliver.util.DeliverConstant.*;
import static com.bestcem.xm.qdes.grpc.v1.services.ProjectStatus.PROJECT_STATUS_ACTIVATED_VALUE;

@Slf4j
@Api(tags = "投放")
@RestController
@RequiredArgsConstructor
@RequestMapping("/deliver/")
public class DeliverController {

    private @NonNull DeliverDeliverTriggerService deliverDeliverTriggerService;
    private @NonNull DeliverDeliverService deliverDeliverService;
    private @NonNull DeliverDefaultDeliverService defaultDeliverService;
    private @NonNull DeliverEmailDeliverService deliverEmailDeliverService;
    private @NonNull DeliverSurveyDeliverService deliverSurveyDeliverService;
    private @NonNull DeliverSmsDeliverService deliverSmsDeliverService;
    private @NonNull DeliverOrgSmsTemplateService deliverOrgSmsTemplateService;
    private @NonNull DeliverSmsTemplateService deliverSmsTemplateService;
    private @NonNull DeliverEmailTemplateService deliverEmailTemplateService;

    private @NonNull QdesGrpcClient qdesGrpcClient;
    private @NonNull DeliverDeliverCheckRecordService deliverCheckRecordService;

    /**
     * 获取EmailTemplate
     * 当url指定id时，直接查询该id的EmailTemplate，忽略其他筛选参数
     * 当url没有指定id时，返回分页查询结果，参数在query中
     */
    @ApiOperation(value = "获取EmailTemplate")
    @GetMapping("/emailtemplates/")
    public ResultPage<DeliverEmailTemplate> emailTemplate(@RequestParam(value = "page", required = false) Integer page,
                                                          @RequestParam(value = "rowsPerPage", required = false) Integer size) {
        return deliverEmailTemplateService.emailTemplate(page, size);
    }

    @ApiOperation(value = "获取一段时间内的问卷id列表")
    @PostMapping("/disturb/delivers/select/surveylist")
    public XmResultJson<?> surveylist(@RequestBody SurveyListParam param) {
        Integer delayTime = Optional.ofNullable(param.getDelayTime()).orElse(90);
        String filterType = "";
        Boolean isFilter = param.getIsCommit();
        if (Objects.nonNull(isFilter) && isFilter) {
            filterType = "commit";
        } else if (Objects.nonNull(isFilter = param.getIsDeliver()) && isFilter) {
            filterType = "deliver";
        }
        List<?> surveyIdList = deliverDeliverService.getTimeRangeSurveyIdList(delayTime, filterType);
        Map<Object, Object> data = new HashMap<>(4);
        data.put("filter_type", filterType);
        data.put("survey_id_list", surveyIdList);
        data.put("num", surveyIdList.size());
        return XmResultJson.success(data);
    }

    @ApiOperation(value = "链接投放-组织链接")
    @GetMapping("/defaultdeliverstore")
    public ResultPage<DeliverStoreVo> getStorePage(@ApiIgnore Page<DeliverDefaultDeliverStore> page, @XmGet GetStorePageParam param) {
        return defaultDeliverService.getStorePage(page, param);
    }

    @ApiOperation(value = "获取单个连接")
    @GetMapping("/deliver/select/{id:[a-fA-F0-9]{24}}")
    public JSONObject getDeliverById(@PathVariable String id, @XmGet GetOneDeliverParam param) {
        return deliverDeliverService.getDeliverById(id, param);
    }

    @ApiOperation(value = "创建专用连接")
    @PostMapping("/dedicateddeliver")
    public JSONObject createDeliver(@RequestBody CreateDeliverParam param) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        JSONObject newJs = new JSONObject();
        newJs.put("id", deliverDeliverService.createDeliver(param));
        return newJs;
    }

    @ApiOperation(value = "获取专用连接")
    @GetMapping("/dedicateddeliver")
    public ResultPage<DedicatedDeliverVo> getDeliver(@ApiIgnore Page<DeliverDedicatedDeliver> page, @XmGet GetDeliverParam param) {
        return deliverDeliverService.getDeliver(page, param);
    }

    @ApiOperation(value = "新建专用链接 填数量")
    @PostMapping("/dedicateddeliver/append")
    public JSONObject appendDeliver(@RequestBody AppendDeliverParam param) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        JSONObject newJs = new JSONObject();
        newJs.put("id", deliverDeliverService.appendDeliver(param));
        return newJs;
    }

    @ApiOperation(value = "获取专用链接下载路径")
    @PostMapping("/survey_dedi_qrcode_tar_download/")
    public JSONObject deliverDownload(@RequestBody DeliverDownloadParam param,
                                      @RequestParam(name = "survey_id") String surveyId, @RequestParam(name = "deliver_id") String deliverId) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        JSONObject newJs = new JSONObject();
        newJs.put("url", deliverDeliverService.getDeliverDownloadPath(surveyId, deliverId, param));
        return newJs;
    }

    @ApiOperation(value = "删除专用链接下载路径")
    @PostMapping("/survey_dedi_deliver_batch_del/")
    public JSONObject deliverDelete(@RequestBody DeliverDownloadParam param,
                                    @RequestParam(name = "survey_id") String surveyId, @RequestParam(name = "deliver_id") String deliverId) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        JSONObject newJs = new JSONObject();
        newJs.put("count", deliverDeliverService.deliverDelete(surveyId, deliverId, param));
        return newJs;
    }

    @ApiOperation(value = "设置单项目免打扰规则")
    @PostMapping("/survey/no_disturb")
    public XmResultJson<?> singleSurveyNoDisturb(@RequestBody JSONObject param) {
        if (!param.containsKey(DELETE_IDS)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有delete_ids");
        }
        if (!param.containsKey(NO_DISTURB_LIST)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有no_disturb_list");
        }
        return deliverDeliverService.singleSurveyNoDisturb(param);
    }

    @ApiOperation(value = "获取单项目免打扰规则")
    @GetMapping("/survey/no_disturb")
    public XmResultJson<Map<String, List<Object>>> getSingleSurveyNoDisturb(@RequestParam(value = "survey_id") String surveyId) {
        return deliverDeliverService.getSingleSurveyNoDisturb(surveyId);
    }

    @ApiOperation(value = "获取组织链接下载路径")
    @GetMapping("/survey_link_qrcode_tar_download/")
    public JSONObject deliverLinkDownload(@XmGet GetDownloadLinkParam param) {
        JSONObject newJs = new JSONObject();
        newJs.put("url", deliverDeliverService.deliverLinkDownload(param));
        return newJs;
    }

    @ApiOperation(value = "获取组织链接下载路径")
    @PostMapping("/survey_qrcode_tar_download/")
    public JSONObject deliverTarDownload(@RequestBody DeliverDefaultDownloadParam param, @RequestParam(name = "survey_id") String surveyId,
                                         @RequestParam(name = "deliver_id") String deliverId, @RequestParam(required = false, name = "root_group_id") String rootGroupId,
                                         @RequestParam(name = "search", required = false) String search) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        JSONObject newJs = new JSONObject();
        newJs.put("url", deliverDeliverService.getDeliverTarPath(surveyId, deliverId, param, rootGroupId, search));
        return newJs;
    }


    @ApiOperation(value = "获取该项目的所有起作用的免打扰规则")
    @GetMapping("/enable/no_disturb")
    public JSONObject getSurveyEnableNoDisturb(@RequestParam(name = "survey_id") String surveyId) {
        List<DeliverDisturbRule> enable_disturb_list = deliverDeliverService.getAllEnableDisturbRule(SecurityContextHolder.getOrgId(), surveyId);
        List<Object> no_disturbrule_list = deliverDeliverService.getNoDisturbProjects(enable_disturb_list);
        JSONObject ret = new JSONObject();
        ret.put("no_disturbrule_list", no_disturbrule_list);
        return ret;
    }

    @ApiOperation(value = "获取全局免打扰")
    @GetMapping("/global/no_disturb")
    public JSONObject getGlobalSurveyNoDisturb(@RequestParam(name = "survey_id", required = false) String surveyId, @RequestParam(name = "enable", required = false) Boolean enable) {
        return deliverDeliverService.getGlobalSurveyNoDisturb(surveyId, enable);
    }

    @ApiOperation(value = "问卷项目列表全局免打扰设置")
    @PostMapping("/global/no_disturb")
    public XmResultJson<?> globalSurveyNoDisturb(@RequestBody JSONObject param) {
        if (!param.containsKey(DELETE_IDS)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有delete_ids");
        }
        if (!param.containsKey(NO_DISTURB_LIST)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有no_disturb_list");
        }
        if (!param.containsKey(AUTO_ADD_DISTURB)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有auto_add_disturb");
        }
        deliverDeliverService.globalSurveyNoDisturb(param);
        return XmResultJson.success();
    }

    @ApiOperation(value = "投放关联奖励")
    @PutMapping("/delivers/{id:[a-fA-F0-9]{24}}/relation/award/")
    public XmResultJson<?> putDeliversAward(@PathVariable String id, @RequestBody JSONObject param) {
        return deliverDeliverService.putDeliversAward(id, param);
    }

    @ApiOperation(value = "数据报表-答卷数据-投放规则")
    @GetMapping("/survey/")
    public JSONObject getSurveyDeliverPage(@XmGet GetSurveyDeliverParam param) {
        return defaultDeliverService.getSurveyDeliverPage(param);
    }

    @ApiOperation(value = "问卷的投放组信息")
    @GetMapping("/qdes/delivergroup/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<?> qdesDeliverGroup(@PathVariable(value = "id") String id) {
        if (StringUtils.isEmpty(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "缺少问卷id");
        }
        return XmResultJson.success(deliverEmailDeliverService.qdesDeliverGroup(id));
    }

    @ApiOperation(value = "邮件投放-详情")
    @GetMapping("/emailrecords/")
    public ResultPage<DeliverEmailRecordVo> emailDeliverRecord(@ApiIgnore Page<DeliverEmailRecord> page, @XmGet EmailRecordsPageParam param) {
        Optional.ofNullable(param.getProjectId())
                .orElseThrow(() -> new BusinessException("project_id required"));

        Optional.ofNullable(param.getEmailDeliverId())
                .orElseThrow(() -> new BusinessException("缺少邮件投放id"));

        ServiceResult<?> res = deliverEmailDeliverService.emailDeliverRecord(page, param);
        if (!res.isSuccess()) {
            throw new BusinessException(res.getErrorCode(), res.getMsg());
        }
        return PageUtil.getResultPage(page.getCurrent(), page.getTotal(), (List<DeliverEmailRecordVo>) res.getData());
    }

    @ApiOperation(value = "答卷详情")
    @GetMapping("/surveys/")
    public XmResultJson<?> surveyDetail(@XmGet SurveyDetailParam param) {
        Optional.ofNullable(param.getProjectId())
                .orElseThrow(() -> new BusinessException("project_id required"));

        Optional.ofNullable(param.getMemberId())
                .orElseThrow(() -> new BusinessException("member_id required"));

        String deliver_id = Optional.of(param.getDeliverId())
                .orElseThrow(() -> new BusinessException("deliver_id required"));

        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliver_id))
                .orElseThrow(() -> new BusinessException(String.format("DeliverDeliver[id=%s] not found", deliver_id)));

        return XmResultJson.success(deliverDeliverService.surveyDetail(deliver, param));
    }

    @ApiOperation(value = "获取催答记录")
    @GetMapping("/urgerecords")
    public XmResultJson<?> urgeRecord(@RequestParam(name = "member_id") String memberId,
                                      @RequestParam(name = "deliver_id", required = false) String deliverId,
                                      @RequestParam(name = "deliver_group_id", required = false) String deliverGroupId) {
        if (StringUtils.isEmpty(deliverId) && StringUtils.isEmpty(deliverGroupId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "投放组id和投放id至少需要一个");
        }
        return XmResultJson.handleServiceResult(deliverEmailDeliverService.urgeRecord(deliverId, memberId, deliverGroupId));
    }

    @ApiOperation(value = "开始投放")
    @PostMapping("/deliver/{id:[a-fA-F0-9]{24}}/start/")
    public JSONObject startDeliver(@PathVariable(value = "id") String deliverId,
                                   @RequestParam(value = "pid") String pid,
                                   HttpServletRequest request) {
        Integer mpTtype = StrUtil.isNotBlank(request.getParameter("mp_ttype")) ? Integer.valueOf(request.getParameter("mp_ttype")) : null;
        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliverId))
                .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", deliverId)));

        //判断项目是否激活
        DeliverSurveyDeliver survey_deliver = deliverSurveyDeliverService.getOne(new QueryWrapper<DeliverSurveyDeliver>().lambda()
                .eq(DeliverSurveyDeliver::getDeliverId, deliver.getId())
                .last("limit 1"));
        if (Objects.isNull(survey_deliver)) {
            throw new BusinessException(String.format("SurveyDeliver[deliver_id=%s] not found", deliverId));
        }

        Project project = qdesGrpcClient.getProject(survey_deliver.getSurveyId());
        if (Objects.nonNull(project) && project.getStatus().getNumber() != PROJECT_STATUS_ACTIVATED_VALUE) {
            throw new BusinessException("项目未激活");
        }

        return deliverDeliverTriggerService.startDeliver(deliver, mpTtype);
    }

    @ApiOperation(value = "结束投放")
    @PostMapping("/deliver/{id:[a-fA-F0-9]{24}}/finish/")
    public JSONObject finishDeliver(@PathVariable(value = "id") String deliverId,
                                    @RequestParam(value = "pid") String pid,
                                    HttpServletRequest request) {
        Integer mpTtype = StrUtil.isNotBlank(request.getParameter("mp_ttype")) ? Integer.parseInt(request.getParameter("mp_ttype")) : WECHATMPDELIVER_MP_TTYPE_DIRECT.getValue();
        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliverId))
                .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", deliverId)));

        return deliverDeliverTriggerService.finishDeliver(deliver, mpTtype);
    }

    @ApiOperation(value = "删除投放")
    @PostMapping("/deliver/{id:[a-fA-F0-9]{24}}/delete/")
    public JSONObject deleteDeliver(@PathVariable(value = "id") String deliverId,
                                    @RequestParam(value = "pid") String pid) {
        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliverId))
                .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", deliverId)));

        deliverDeliverTriggerService.deleteDeliver(deliver);
        JSONObject ret = new JSONObject();
        ret.put("status", true);
        return ret;
    }

    @ApiOperation(value = "审核投放")
    @PostMapping("/deliver/{id:[a-fA-F0-9]{24}}/checksubmit/")
    public JSONObject checkDeliver(@PathVariable(value = "id") String deliverId) {
        //判断项目是否激活
        DeliverSurveyDeliver survey_deliver = deliverSurveyDeliverService.getOne(new QueryWrapper<DeliverSurveyDeliver>().lambda()
            .eq(DeliverSurveyDeliver::getDeliverId, deliverId)
            .last("limit 1"));
        if (Objects.isNull(survey_deliver)) {
            throw new BusinessException(String.format("SurveyDeliver[deliver_id=%s] not found", deliverId));
        }

        Project project = qdesGrpcClient.getProject(survey_deliver.getSurveyId());
        if (Objects.nonNull(project) && project.getStatus().getNumber() != PROJECT_STATUS_ACTIVATED_VALUE) {
            throw new BusinessException("项目未激活");
        }

        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliverId))
            .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", deliverId)));
        int status = deliver.getStatus();
        if (DeliverStatusEnum.DELIVER_STATUS_STOP.getValue() != status
        && DeliverStatusEnum.DELIVER_STATUS_UNREVIEWED.getValue() != status
        && DeliverStatusEnum.DELIVER_STATUS_REVIEW_FAIL.getValue() != status) {
            throw new BusinessException("当前投放状态不支持审核进入审核中");
        }
        deliverDeliverService.update(null, new LambdaUpdateWrapper<DeliverDeliver>().set(DeliverDeliver::getStatus, DeliverStatusEnum.DELIVER_STATUS_UNDER_REVIEW).eq(DeliverDeliver::getId, deliverId));
        deliverDeliverTriggerService.deliverEmailCheckNotice(deliver.getChannel(), deliverId, project);
        JSONObject reJs = new JSONObject();
        reJs.put("status", true);
        return reJs;
    }

    @ApiOperation(value = "审核通过")
    @PostMapping("/deliver/{id:[a-fA-F0-9]{24}}/reviewsucess/")
    public JSONObject sucessDeliver(@PathVariable(value = "id") String deliverId) {
        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliverId))
            .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", deliverId)));
        int status = deliver.getStatus();
        if (DeliverStatusEnum.DELIVER_STATUS_FINISH.getValue() == status) {
            throw new BusinessException("该投放已结束");
        }
        if (DeliverStatusEnum.DELIVER_STATUS_REVIEW_SUCCESS.getValue() == status) {
            throw new BusinessException("该投放已审核通过");
        }
        if (DeliverStatusEnum.DELIVER_STATUS_REVIEW_FAIL.getValue() == status) {
            throw new BusinessException("该投放已审核驳回");
        }
        if (DeliverStatusEnum.DELIVER_STATUS_UNDER_REVIEW.getValue() != status) {
            throw new BusinessException("当前投放状态不支持审核成功提交");
        }
        deliverDeliverService.update(null, new LambdaUpdateWrapper<DeliverDeliver>().set(DeliverDeliver::getStatus, DeliverStatusEnum.DELIVER_STATUS_REVIEW_SUCCESS).eq(DeliverDeliver::getId, deliverId));
        deliverDeliverTriggerService.triggerDeliverStatus(deliver, "review_success");
        JSONObject reJs = new JSONObject();
        reJs.put("status", true);
        DeliverDeliverCheckRecord record = new DeliverDeliverCheckRecord();
        record.setOrgId(deliver.getOrgId());
        record.setDeliverId(deliverId);
        record.setCheckStatus(1);
        record.setCheckComment("");
        record.setCheckUser(SecurityContextHolder.getUserId());
        record.setOrgId(SecurityContextHolder.getOrgId());
        deliverCheckRecordService.save(record);
        log.info("End to sucessDeliver");
        reJs.put("id", record.getId());
        return reJs;
    }

    @ApiOperation(value = "审核驳回")
    @PostMapping("/deliver/{id:[a-fA-F0-9]{24}}/reviewfail/")
    public JSONObject failDeliver(@PathVariable(value = "id") String deliverId, @RequestBody JSONObject param) {
        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(deliverId))
            .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", deliverId)));
        int status = deliver.getStatus();
        if (DeliverStatusEnum.DELIVER_STATUS_FINISH.getValue() == status) {
            throw new BusinessException("该投放已结束");
        }
        if (DeliverStatusEnum.DELIVER_STATUS_REVIEW_SUCCESS.getValue() == status) {
            throw new BusinessException("该投放已审核通过");
        }
        if (DeliverStatusEnum.DELIVER_STATUS_REVIEW_FAIL.getValue() == status) {
            throw new BusinessException("该投放已审核驳回");
        }
        if (DeliverStatusEnum.DELIVER_STATUS_UNDER_REVIEW.getValue() != status) {
            throw new BusinessException("当前投放状态不支持审核成功提交");
        }
        String checkComment = param.getString("check_comment");
        if (StringUtils.isBlank(checkComment)) {
            throw new BusinessException("审核驳回原因不能为空");
        }
        deliverDeliverService.update(null, new LambdaUpdateWrapper<DeliverDeliver>().set(DeliverDeliver::getStatus, DeliverStatusEnum.DELIVER_STATUS_REVIEW_FAIL).eq(DeliverDeliver::getId, deliverId));

        JSONObject reJs = new JSONObject();
        reJs.put("status", true);
        DeliverDeliverCheckRecord record = new DeliverDeliverCheckRecord();
        record.setOrgId(deliver.getOrgId());
        record.setDeliverId(deliverId);
        record.setCheckStatus(0);
        record.setCheckComment(checkComment);
        record.setCheckUser(SecurityContextHolder.getUserId());
        record.setOrgId(SecurityContextHolder.getOrgId());
        deliverCheckRecordService.save(record);
        log.info("End to sucessDeliver");
        reJs.put("id", record.getId());
        return reJs;
    }

    @ApiOperation(value = "查看审核日志")
    @GetMapping("/deliver/{id:[a-fA-F0-9]{24}}/records/")
    public List<DeliverDeliverCheckRecord> recordDeliver(@PathVariable(value = "id") String deliverId) {
        List<DeliverDeliverCheckRecord> records = deliverCheckRecordService.list(new LambdaQueryWrapper<DeliverDeliverCheckRecord>()
            .eq(DeliverDeliverCheckRecord::getDeliverId, deliverId).orderByDesc(DeliverDeliverCheckRecord::getCreatedDt));
        log.info("End to recordDeliver, deliverId = {}", deliverId);
        return records;
    }

    @ApiOperation(value = "邮件投放-更新")
    @PutMapping("/emaildelivers/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<?> updateEmailDelivers(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        return XmResultJson.handleServiceResult(deliverEmailDeliverService.updateEmailDelivers(id, param));
    }

    @ApiOperation(value = "邮件投放-编辑")
    @PutMapping("/emaildelivers/edit/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<?> editEmailDelivers(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        if (StringUtils.isEmpty(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith id");
        }
        return XmResultJson.handleServiceResult(deliverEmailDeliverService.editEmailDelivers(id, param));
    }

    @ApiOperation(value = "邮件投放-导出")
    @PostMapping("/emaildeliver/export/")
    public void emailDeliverExport(@RequestBody JSONObject param, HttpServletResponse response) {
        log.info("/emaildeliver/export/传递参数param:{}", param.toJSONString());
        Optional.ofNullable(param.getString("project_id"))
                .orElseThrow(() -> new BusinessException("project_id required"));

        String emailDeliverId = param.getString("email_deliver_id");
        DeliverEmailDeliver emailDeliver = Optional.ofNullable(deliverEmailDeliverService.getById(emailDeliverId))
                .orElseThrow(() -> new BusinessException(String.format("EmailDeliver[id=%s] not found", emailDeliverId)));

        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(emailDeliver.getDeliverId()))
                .orElseThrow(() -> new BusinessException(String.format("DeliverDeliver[id=%s] not found", emailDeliver.getDeliverId())));

        deliverEmailDeliverService.emailDeliverExport(param, response, emailDeliver, deliver);
    }

    @ApiOperation(value = "邮件投放-重新投放")
    @PostMapping("/{id:[a-fA-F0-9]{24}}/emaildeliver/again/")
    public XmResultJson<?> emailDeliverAgain(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        Optional.ofNullable(id).orElseThrow(() -> new BusinessException("project_id required"));

        String emailDeliverId = param.getString("email_deliver_id");
        Optional.ofNullable(emailDeliverId)
                .orElseThrow(() -> new BusinessException("缺少邮件投放id"));
        DeliverEmailDeliver emailDeliver = Optional.ofNullable(deliverEmailDeliverService.getById(emailDeliverId))
                .orElseThrow(() -> new BusinessException(String.format("EmailDeliver[id=%s] not found", emailDeliverId)));

        return XmResultJson.handleServiceResult(deliverEmailDeliverService.emailDeliverAgain(id, param, emailDeliver));
    }

    @ApiOperation(value = "邮件投放-答卷详情-催答")
    @PostMapping("/{id:[a-fA-F0-9]{24}}/emaildeliver/urge/")
    public XmResultJson<?> emailDeliverUrge(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        Optional.ofNullable(id).orElseThrow(() -> new BusinessException("project_id required"));
        return XmResultJson.handleServiceResult(deliverEmailDeliverService.emailDeliverUrge(id, param));
    }

    @ApiOperation(value = "短信投放-答卷详情-催答")
    @PostMapping("/{id:[a-fA-F0-9]{24}}/smsdeliver/urge/")
    public XmResultJson<?> smsDeliverUrge(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        Optional.ofNullable(id).orElseThrow(() -> new BusinessException("project_id required"));
        return XmResultJson.handleServiceResult(deliverSmsDeliverService.smsDeliverUrge(id, param));
    }

    @ApiOperation(value = "短信投放-导出")
    @PostMapping("/smsdeliver/export/")
    public void smsDeliverExport(@RequestBody JSONObject param, HttpServletResponse response) {
        log.info("/smsDeliverExport/export/传递参数param:{}", param.toJSONString());
        Optional.ofNullable(param.getString("project_id"))
                .orElseThrow(() -> new BusinessException("project_id required"));

        String smsDeliverId = param.getString("sms_deliver_id");
        DeliverSmsDeliver smsDeliver = Optional.ofNullable(deliverSmsDeliverService.getById(smsDeliverId))
                .orElseThrow(() -> new BusinessException(String.format("SmsDeliver[id=%s] not found", smsDeliverId)));

        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(smsDeliver.getDeliverId()))
                .orElseThrow(() -> new BusinessException(String.format("DeliverDeliver[id=%s] not found", smsDeliver.getDeliverId())));

        deliverSmsDeliverService.smsDeliverExport(param, response, smsDeliver, deliver);
    }

    @ApiOperation(value = "短信投放-编辑")
    @PutMapping("/smsdelivers/edit/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<?> editSmsDelivers(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        if (StringUtils.isEmpty(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith id");
        }
        return XmResultJson.handleServiceResult(deliverSmsDeliverService.editSmsDelivers(id, param));
    }

    @ApiOperation(value = "短信投放-详情")
    @GetMapping("/smsrecords/")
    public ResultPage<DeliverSmsRecordVo> smsDeliverRecord(@ApiIgnore Page<DeliverSmsRecord> page, @XmGet SmsRecordsPageParam param) {
        Optional.ofNullable(param.getProjectId())
                .orElseThrow(() -> new BusinessException("project_id required"));

        Optional.ofNullable(param.getSmsDeliverId())
                .orElseThrow(() -> new BusinessException("缺少短信投放id"));

        ServiceResult<?> res = deliverSmsDeliverService.smsDeliverRecord(page, param);
        if (!res.isSuccess()) {
            throw new BusinessException(res.getErrorCode(), res.getMsg());
        }
        return PageUtil.getResultPage(page.getCurrent(), page.getTotal(), (List<DeliverSmsRecordVo>) res.getData());
    }

    /**
     * 获取SMSTemplate
     * 当url指定id时，直接查询该id的SMSTemplate，忽略其他筛选参数
     * 当url没有指定id时，返回分页查询结果，参数在query中
     */
    @ApiOperation(value = "获取SMSTemplate")
    @GetMapping("/smstemplates/")
    public ResultPage<DeliverSmsTemplate> smsTemplate(@RequestParam(value = "page", required = false) Integer page,
                                                      @RequestParam(value = "rowsPerPage", required = false) Integer size) {
        return deliverSmsTemplateService.smsTemplate(page, size);
    }

    /**
     * 获取OrgSMSTemplate
     * 当url指定id时，直接查询该id的OrgSMSTemplate，忽略其他筛选参数
     * 当url没有指定id时，返回分页查询结果，参数在query中
     */
    @ApiOperation(value = "获取OrgSMSTemplate")
    @GetMapping("/orgsmstemplates/")
    public ResultPage<DeliverOrgSmsTemplate> orgSmsTemplates(@RequestParam(value = "page", required = false) Integer page,
                                                             @RequestParam(value = "rowsPerPage", required = false) Integer size) {
        return deliverOrgSmsTemplateService.orgSmsTemplates(page, size);
    }

    @ApiOperation(value = "短信投放-更新")
    @PutMapping("/smsdelivers/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<?> updateSmsDelivers(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        if (StringUtils.isEmpty(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith id");
        }
        return XmResultJson.handleServiceResult(deliverSmsDeliverService.updateSmsDelivers(id, param));
    }

    @ApiOperation(value = "短信投放-重新投放")
    @PostMapping("/{id:[a-fA-F0-9]{24}}/smsdeliver/again/")
    public XmResultJson<?> smsDeliverAgain(@PathVariable(value = "id") String id, @RequestBody JSONObject param) {
        Optional.ofNullable(id).orElseThrow(() -> new BusinessException("project_id required"));

        String smsDeliverId = param.getString("sms_deliver_id");
        Optional.ofNullable(smsDeliverId)
                .orElseThrow(() -> new BusinessException("缺少短信投放id"));
        DeliverSmsDeliver smsDeliver = Optional.ofNullable(deliverSmsDeliverService.getById(smsDeliverId))
                .orElseThrow(() -> new BusinessException(String.format("SmsDeliver[id=%s] not found", smsDeliverId)));

        return XmResultJson.handleServiceResult(deliverSmsDeliverService.smsDeliverAgain(id, param, smsDeliver));
    }
}